#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
自定义异常类
Custom Exceptions

定义项目中使用的自定义异常类，用于更精确的错误处理
"""


class GimbalControlError(Exception):
    """云台控制基础异常类"""

    def __init__(self, message: str, error_code: str = None):
        """
        初始化云台控制异常

        Args:
            message: 错误信息
            error_code: 错误代码（可选）
        """
        super().__init__(message)
        self.message = message
        self.error_code = error_code


class GimbalAngleOutOfRangeError(GimbalControlError):
    """云台角度超出范围异常"""

    def __init__(self, axis: str, angle: float, min_angle: float, max_angle: float):
        """
        初始化角度超出范围异常

        Args:
            axis: 轴名称 ('pan' 或 'tilt')
            angle: 请求的角度
            min_angle: 最小允许角度
            max_angle: 最大允许角度
        """
        self.axis = axis
        self.angle = angle
        self.min_angle = min_angle
        self.max_angle = max_angle

        axis_name = "水平" if axis == "pan" else "垂直"
        message = f"{axis_name}角度超出范围: {angle}° (范围: {min_angle}-{max_angle}°)"

        super().__init__(message, error_code="ANGLE_OUT_OF_RANGE")

    def to_dict(self):
        """转换为字典格式，便于API返回"""
        axis_name = "水平" if self.axis == "pan" else "垂直"
        return {
            "error_type": "angle_out_of_range",
            "error_code": self.error_code,
            "message": self.message,
            "details": {
                "axis": self.axis,
                "axis_name": axis_name,
                "requested_angle": self.angle,
                "min_allowed": self.min_angle,
                "max_allowed": self.max_angle,
                "valid_range": f"{self.min_angle}-{self.max_angle}°"
            }
        }


class GimbalNotConnectedError(GimbalControlError):
    """云台未连接异常"""

    def __init__(self):
        message = "云台控制器未连接"
        super().__init__(message, error_code="GIMBAL_NOT_CONNECTED")

    def to_dict(self):
        """转换为字典格式"""
        return {
            "error_type": "gimbal_not_connected",
            "error_code": self.error_code,
            "message": self.message,
            "details": {
                "suggestion": "请检查云台硬件连接和串口配置"
            }
        }


class GimbalMoveError(GimbalControlError):
    """云台移动失败异常"""

    def __init__(self, axis: str, angle: float, reason: str = None):
        """
        初始化云台移动失败异常

        Args:
            axis: 轴名称 ('pan' 或 'tilt')
            angle: 目标角度
            reason: 失败原因（可选）
        """
        self.axis = axis
        self.angle = angle
        self.reason = reason

        axis_name = "水平" if axis == "pan" else "垂直"
        base_message = f"{axis_name}舵机移动失败: {angle}°"
        if reason:
            message = f"{base_message} - {reason}"
        else:
            message = base_message

        super().__init__(message, error_code="GIMBAL_MOVE_FAILED")

    def to_dict(self):
        """转换为字典格式"""
        axis_name = "水平" if self.axis == "pan" else "垂直"
        details = {
            "axis": self.axis,
            "axis_name": axis_name,
            "target_angle": self.angle
        }
        if self.reason:
            details["failure_reason"] = self.reason

        return {
            "error_type": "gimbal_move_failed",
            "error_code": self.error_code,
            "message": self.message,
            "details": details
        }


class FaceDetectionError(Exception):
    """人脸检测异常类"""

    def __init__(self, message: str, error_code: str = None):
        """
        初始化人脸检测异常

        Args:
            message: 错误信息
            error_code: 错误代码（可选）
        """
        super().__init__(message)
        self.message = message
        self.error_code = error_code or "FACE_DETECTION_ERROR"

    def to_dict(self):
        """转换为字典格式"""
        return {
            "error_type": "face_detection_error",
            "error_code": self.error_code,
            "message": self.message
        }